<?php

namespace app\common\service;

use app\common\exception\BusinessException;
use think\facade\Cache;

class BdBceService
{
    /**
     * @var string
     */
    protected $host = '';

    /**
     * @var
     */
    protected $client_id;

    /**
     * @var
     */
    protected $client_secret;

    /**
     * 构造函数
     * @param $client_id
     * @param $client_secret
     */
    public function __construct($host, $client_id, $client_secret)
    {
        $this->host = $host;
        $this->client_id = $client_id;
        $this->client_secret = $client_secret;
    }

    /**
     * 获取AccessToken
     * @return mixed|string
     * @throws BusinessException
     */
    public function getAccessToken()
    {
        // 缓存KEY
        $cacheKey = 'bd-ai-' . md5($this->client_id);
        $accessToken = Cache::get($cacheKey);
        if ($accessToken) {
            return $accessToken;
        }

        // 组装参数
        $postData = array(
            'grant_type' => 'client_credentials',
            'client_id' => $this->client_id,
            'client_secret' => $this->client_secret
        );

        // 发起请求
        $api = "https://aip.baidubce.com/oauth/2.0/token";
        $data = http_build_query($postData);
        $response = curl($api, $data, false, [], 3);
        if (!$response) {
            throw new BusinessException('调用accessToken失败,接口未响应内容');
        }
        $responseData = json_decode($response, true);
        if (!$responseData) {
            throw new BusinessException('调用accessToken失败,接口返回非Json');
        }

        // 提取accessToken
        $access_token = $responseData['access_token'] ?? '';
        if (!$access_token) {
            throw new BusinessException('调用accessToken失败,接口未返回access_token');
        }

        // 保存accessToken,15天有效
        if (!Cache::set($cacheKey, $access_token, 86400 * 15)) {
            throw new BusinessException('保存access_token失败');
        }

        // 返回
        return $access_token;
    }

    /**
     * ocrExecute
     * @param $api
     * @param $data
     * @return mixed
     * @throws BusinessException
     */
    public function ocrExecute($api, $data)
    {
        // 请求api
        $api = $this->host . $api . '?access_token=' . $this->getAccessToken();

        // 请求头
        $header = array(
            'Content-Type: application/x-www-form-urlencoded',
            'Accept: application/json'
        );

        // 发起请求
        $data = http_build_query($data);
        $response = curl($api, $data, false, $header, 1);
        if (!$response) {
            throw new BusinessException('调用ocr失败,接口未响应内容');
        }
        $responseData = json_decode($response, true);
        if (!$responseData) {
            throw new BusinessException('调用ocr失败,接口返回非Json');
        }

        // 返回
        return $responseData;
    }

    /**
     * speechExecute
     * @param $api
     * @param $data
     * @return mixed
     * @throws BusinessException
     */
    public function speechExecute($api, $data)
    {
        // 请求api
        $api = $this->host . $api;

        // 请求头
        $header = [
            'Content-Type: application/json',
            'Accept: application/json'
        ];

        // 填充token
        $data['token'] = $this->getAccessToken();

        // 发起请求
        $response = curl($api, json_encode($data), false, $header, 1);
        if (!$response) {
            throw new BusinessException('调用' . $api . '失败,接口未响应内容');
        }
        $responseData = json_decode($response, true);
        if (!$responseData) {
            throw new BusinessException('调用' . $api . '失败,接口返回非Json');
        }

        // 返回
        return $responseData;
    }
}